---
title: SAIF.Services.Printing operations and processes
summary: Business and technical operations supported by this library.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-08-21
library: SAIF.Services.Printing
reference_type: embedded
---

# SAIF.Services.Printing operations and processes

This page is the operation catalog for `SAIF.Services.Printing`: the xPression print/preview/distribute
gateway (`clsPrint`), the SSRS rendering gateway (`clsRSPrint`), the report lifecycle (`ReportBase`), and the
xPression XML document builder (`XDesignXElement` / `XDesignXDocument`). The library performs no database
access; no operation reads from or writes to a database.

## Operation catalog

| Operation | Intent | Trigger | Inputs | Outputs | Rules |
| --- | --- | --- | --- | --- | --- |
| [OP-01 — Preview a document](operations/op-01-preview-a-document.md) | Render a document from a package/XML pair without printing or distributing it | `clsPrint.previewDocument` invoked | Package name, xPression data XML, optional output profile | Rendered document bytes | [BR-PRT-001](business-rules.md#br-prt-001-package-name-extension-normalization) |
| [OP-02 — Preview as PDF](operations/op-02-preview-as-pdf.md) | Render a package/XML pair specifically as PDF | `clsPrint.previewPDF` invoked | Package name, xPression data XML | PDF bytes | [BR-PRT-001](business-rules.md#br-prt-001-package-name-extension-normalization) |
| [OP-03 — Print rendered bytes](operations/op-03-print-rendered-bytes.md) | Send already-rendered bytes to a physical printer | `clsPrint.printPDF` invoked | Byte array, `Printer`, `PlexMode`, `Copies`, `ScaleMode` | `True` (unconditional) | [BR-PRT-013](business-rules.md#br-prt-013-print-and-distribute-report-unconditional-success) |
| [OP-04 — Distribute a document](operations/op-04-distribute-a-document.md) | Distribute a document via MSMQ queue or direct xPression call, covering print, imaging, e-mail, fax, or deferred output | `clsPrint.distributeDocument` invoked | Package, XML, plus instance state (`Printer`, `PlexMode`, `Copies`, `ScaleMode`, `Format`, `OutputProfile`, `ImportInfo`, `EmailInfo`, `FaxInfo`, `DeferredInfo`, `IDMPath`) | `True`; queued MSMQ message or SOAP call side effect | [BR-PRT-001](business-rules.md#br-prt-001-package-name-extension-normalization), [BR-PRT-003](business-rules.md#br-prt-003-synchronous-versus-queued-distribution), [BR-PRT-004](business-rules.md#br-prt-004-transactional-msmq-send), [BR-PRT-005](business-rules.md#br-prt-005-msmq-failure-rollback), [BR-PRT-006](business-rules.md#br-prt-006-fixed-paper-tray-for-synchronous-distribution), [BR-PRT-013](business-rules.md#br-prt-013-print-and-distribute-report-unconditional-success) |
| [OP-05 — MSMQ transaction management](operations/op-05-msmq-transaction-management.md) | Batch one or more `distributeDocument` calls into a single transactional unit of work | `StartMQTransaction` / `EndMQTransaction` invoked by caller | None / commit-or-abort flag | Committed or aborted `MessageQueueTransaction` | [BR-PRT-004](business-rules.md#br-prt-004-transactional-msmq-send) |
| [OP-06 — Report render lifecycle](operations/op-06-report-render-lifecycle.md) | Build and render a report's xPression XML into document bytes, with caching | `ReportBase.Render` invoked (directly, or via `Print`/`Save`) | `overwrite` flag, `ReportPackage`, `OutputProfile`, report XML from `Create` | `Boolean` success; populates `ReportFile` | [BR-PRT-007](business-rules.md#br-prt-007-render-result-caching), [BR-PRT-008](business-rules.md#br-prt-008-render-and-distribute-preconditions), [BR-PRT-009](business-rules.md#br-prt-009-default-printer-and-security-platform-selection), [BR-PRT-010](business-rules.md#br-prt-010-non-throwing-render-and-distribute-failures) |
| [OP-07 — Report print](operations/op-07-report-print.md) | Print a rendered report to a caller-supplied printer | `ReportBase.Print` invoked | Printer name, cached or freshly rendered `ReportFile` | `True`/`False` | [BR-PRT-007](business-rules.md#br-prt-007-render-result-caching) |
| [OP-08 — Report distribute](operations/op-08-report-distribute.md) | Distribute a report's raw XML through `clsPrint.distributeDocument` | `ReportBase.Distribute` invoked | `overwrite` flag, `ReportPackage`, report XML from `Create` | `Boolean` success | [BR-PRT-008](business-rules.md#br-prt-008-render-and-distribute-preconditions), [BR-PRT-010](business-rules.md#br-prt-010-non-throwing-render-and-distribute-failures) |
| [OP-09 — Report save to disk](operations/op-09-report-save-to-disk.md) | Write a rendered report's bytes to a destination file | `ReportBase.Save` invoked | `DestinationFileName`, `overwrite` flag | `Boolean` — whether the destination file now exists | [BR-PRT-014](business-rules.md#br-prt-014-destination-file-overwrite-protection) |
| [OP-10 — Output profile selection](operations/op-10-output-profile-selection.md) | Select the `PDF` or `PDF_Draft_Watermark` output profile before rendering | `SetDefaultProfile` / `SetDraftProfile` invoked | None | `OutputProfile` set to a fixed constant | [BR-PRT-015](business-rules.md#br-prt-015-draft-versus-final-output-profile) |
| [OP-11 — Build xPression XML](operations/op-11-build-xpression-xml.md) | Serialize an `XDesignXElement`/`XDesignXDocument` tree into the xPression XML dialect, propagating keys for nested repeating sections | `ToXpression()` invoked (directly, or via `ReportBase.Render`) | An `XDesignXElement`/`XDesignXDocument` tree with keys/foreign keys set via `AddKey` | xPression-dialect XML string | [BR-PRT-016](business-rules.md#br-prt-016-key-propagation-for-nested-repeating-sections), [BR-PRT-017](business-rules.md#br-prt-017-empty-value-self-closing-elements), [BR-PRT-018](business-rules.md#br-prt-018-xml-value-escaping), [BR-PRT-019](business-rules.md#br-prt-019-empty-serialization-for-malformed-documents) |
| [OP-12 — Render an SSRS report](operations/op-12-render-an-ssrs-report.md) | Load, parameterise, and render an SSRS catalog report to the selected format | `clsRSPrint.PreviewDocument` invoked | `ReportPath`, `Format`/`ImageFormat`, accumulated parameters | Rendered bytes | [BR-PRT-011](business-rules.md#br-prt-011-rendered-file-extension-fixed-by-format), [BR-PRT-020](business-rules.md#br-prt-020-ssrs-execution-under-hosting-process-identity) |

## Process flow diagram
The following diagram visualizes the primary distribute-document flow, including the MSMQ-versus-direct dispatch
decision described in OP-04.

```mermaid
flowchart TD
	Start([distributeDocument called]) --> SetPkg[Normalize package name<br>BR-PRT-001]
	SetPkg --> Decision{Asynchronous?}
	Decision -->|Yes| Tx[Start/reuse MSMQ transaction<br>BR-PRT-004]
	Tx --> Queue[Send CompositeRequestClass<br>BinaryMessageFormatter]
	Queue --> Commit[Commit transaction]
	Commit --> EndYes([Return True])
	Tx -->|Exception| Rollback[Rollback and rethrow<br>BR-PRT-005]
	Decision -->|No| Direct[Call xPression distributeDocument<br>Tray2 fixed, BR-PRT-006]
	Direct --> EndNo([Return True])
```

## Failure and edge-case behavior
- `printPDF` and the synchronous branch of `distributeDocument` always return `True`; downstream failures surface
  only as thrown exceptions, never as a `False` return ([BR-PRT-013](business-rules.md#br-prt-013-print-and-distribute-report-unconditional-success)).
- `ReportBase.Render` and `ReportBase.Distribute` catch any exception, append an `ErrorDetail` to `Errors`, and
  return `False` rather than propagating the exception ([BR-PRT-010](business-rules.md#br-prt-010-non-throwing-render-and-distribute-failures)).
- A failure while queueing an asynchronous distribution rolls back the MSMQ transaction and re-throws, so no
  partially queued message survives ([BR-PRT-005](business-rules.md#br-prt-005-msmq-failure-rollback)).
- `clsRSPrint.DistributeDocument` always throws `NotImplementedException` — SSRS distribution is not supported
  ([BR-PRT-012](business-rules.md#br-prt-012-ssrs-distribution-not-supported)).
- `XDesignXDocument.ToXpression` returns an empty string when the document has no root, or the root is not an
  `XDesignXElement`, instead of raising an error ([BR-PRT-019](business-rules.md#br-prt-019-empty-serialization-for-malformed-documents)).
- `ReportBase.xPrint` constructs its `clsPrint` with the parameterless constructor, so an environment service
  injected into the report is not propagated to the printer it uses.*

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Business rules](business-rules.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Services.Printing/clsPrint.vb`
- `SAIF.Services.Printing/clsRSPrint.vb`
- `SAIF.Services.Printing/Reporting/IReport.vb`
- `SAIF.Services.Printing/Reporting/ReportBase.vb`
- `SAIF.Services.Printing/Reporting/XDesignXDocument.vb`
- `SAIF.Services.Printing/Reporting/XDesignXElement.vb`
- SAIF.Services.Printing/clsPrint.vb
- SAIF.Services.Printing/clsRSPrint.vb
- SAIF.Services.Printing/Reporting/ReportBase.vb
- SAIF.Services.Printing/Reporting/XDesignXDocument.vb
- SAIF.Services.Printing/Reporting/XDesignXElement.vb
